package com.moss.cloud.log.service.impl;

import com.moss.cloud.common.core.constant.Constant;
import com.moss.cloud.common.core.model.Result;
import com.moss.cloud.common.core.model.vo.CustomPage;
import com.moss.cloud.common.core.utils.BooleanHandel;
import com.moss.cloud.common.core.utils.MongoPageUtil;
import com.moss.cloud.common.core.utils.UserContextHolder;
import com.moss.cloud.log.model.param.OpsLogParam;
import com.moss.cloud.log.model.po.OperationLog;
import com.moss.cloud.log.service.IOperationLogService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 系统操作日志业务处理层
 *
 * @author 瑾年
 * @date 2023年3月19日
 */
@Service
public class OperationLogServiceImpl implements IOperationLogService {
    private MongoTemplate mongoTemplate;

    public OperationLogServiceImpl(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    /**
     * 保存系统操作日志
     *
     * @param operationLog
     * @return
     */
    @Override
    public Mono<Result> saveOperationLog(OperationLog operationLog) {
        operationLog.setId(UUID.randomUUID().toString());
        mongoTemplate.insert(operationLog);
        return Mono.just(Result.success());
    }


    /**
     * 系统操作日志列表
     *
     * @param opsLogParam
     * @return
     */
    @Override
    public CustomPage<OperationLog> opsLogPage(OpsLogParam opsLogParam) {
        Query query = new Query();
        //创建排序规则
        Sort sort = Sort.by(Sort.Direction.DESC, "creatDate");
        query.with(sort);
        Criteria criteria = new Criteria();
        BooleanHandel.isTrue(StringUtils.isNoneBlank(opsLogParam.getServerName())).trueHandle(() ->
                criteria.and("serverName").is(opsLogParam.getServerName()));
        BooleanHandel.isTrue(StringUtils.isNoneBlank(opsLogParam.getOperation())).trueHandle(() ->
                criteria.and("operation").regex(Pattern.compile("^.*" + opsLogParam.getOperation() + ".*$", Pattern.CASE_INSENSITIVE)));
        BooleanHandel.isTrue(StringUtils.isNoneBlank(opsLogParam.getUsername())).trueHandle(() ->
                criteria.and("userName").regex(Pattern.compile("^.*" + opsLogParam.getUsername() + ".*$", Pattern.CASE_INSENSITIVE)));
        Long tenantId = UserContextHolder.getTenantId();
        BooleanHandel.isTrue(Objects.nonNull(opsLogParam.getTenantId()) && tenantId.equals(Constant.SUPER_TENANT)).trueHandle(() ->
                criteria.and("tenantId").is(opsLogParam.getTenantId()));
        BooleanHandel.isTrue(!tenantId.equals(Constant.SUPER_TENANT)).trueHandle(()-> criteria.and("tenantId").is(tenantId));
        query.addCriteria(criteria);
        Long total = mongoTemplate.count(query,OperationLog.class);
        query.with(PageRequest.of(opsLogParam.getCurrent().intValue() - 1, opsLogParam.getSize().intValue()));
        List<OperationLog> operationLogs = mongoTemplate.find(query, OperationLog.class);
        return MongoPageUtil.customPage(operationLogs, opsLogParam.getCurrent(), opsLogParam.getSize(), total);
    }
}
